package models

import (
	"fmt"
	"github.com/astaxie/beego/orm"
	"strconv"
	"strings"
	"time"
)

//模型定义接口文档
//https://beego.me/docs/mvc/model/models.md
type Book struct {
	BookId         int       `orm:"pk;auto" json:"book_id"`              // book id
	BookName       string    `orm:"size(500)" json:"book_name"`          // 书名
	Identify       string    `orm:"size(500);unique" json:"identify"`    // 唯一标识
	OrderIndex     int       `orm:"defalut(0)" json:"order_index"`       // 排序序号
	Description    string    `orm:"size(1000)" json:"description"`       // 图书描述
	Cover          string    `orm:"size(1000)" json:"cover"`             //封面地址
	Editor         string    `orm:"size(50)" json:"editor"`              //编辑器类型: "markdown"
	Status         int       `orm:"default(0)" json:"status"`            //状态:0 正常 ; 1 已删除
	PrivatelyOwned int       `orm:"default(0)" json:"privately_owned"`   // 是否私有: 0 公开 ; 1 私有
	PrivateToken   string    `orm:"size(500);null" json:"private_token"` // 私有图书访问Token
	MemberId       int       `orm:"size(100)" json:"member_id"`
	CreateTime     time.Time `orm:"type(datetime);auto_now_add" json:"create_time"` //创建时间
	ModifyTime     time.Time `orm:"type(datetime);auto_now_add" json:"modify_time"`
	ReleaseTime    time.Time `orm:"type(datetime);" json:"release_time"` //发布时间
	DocCount       int       `json:"doc_count"`                          //文档数量
	CommentCount   int       `orm:"type(int)" json:"comment_count"`
	Vcnt           int       `orm:"default(0)" json:"vcnt"`              //阅读次数
	Collection     int       `orm:"column(star);default(0)" json:"star"` //收藏次数
	Score          int       `orm:"default(40)" json:"score"`            //评分
	CntScore       int       //评分人数
	CntComment     int       //评论人数
	Author         string    `orm:"size(50)"`                      //来源
	AuthorURL      string    `orm:"column(author_url);size(1000)"` //来源链接
}

func (m *Book) TableName() string {
	return TNBook()
}

func NewBook() *Book {
	return &Book{}
}

/**
根据添加获取书籍列表
*/
func (m *Book) HomeData(pageIndex int, pageSize int, cid int, fields ...string) (books []Book, totalCount int, err error) {
	if len(fields) == 0 {
		fields = append(fields, "book_id", "book_name", "identify", "cover", "order_index")
	}

	fieldStr := "b." + strings.Join(fields, ",b.")

	//strconv.Itoa int 转字符串
	sqlFmt := "select %v from " + TNBook() + " b left join " + TNBookCategory() + " c on b.book_id = c.book_id  where c.category_id=" + strconv.Itoa(cid)

	sql := fmt.Sprintf(sqlFmt, fieldStr)
	sqlCount := fmt.Sprintf(sqlFmt, "count(*) cnt")

	o := orm.NewOrm()
	// 定义返回值结构
	var params []orm.Params

	if _, err := o.Raw(sqlCount).Values(&params); err == nil {
		if len(params) > 0 {
			totalCount, _ = strconv.Atoi(params[0]["cnt"].(string))
		} else {
		}
	}

	_, err = o.Raw(sql).QueryRows(&books)
	return
}

/**
通关关键字查询相关的图书（书名和描述）
*/
func (m *Book) SearchBook(keyword string, page int, size int) (books []Book, cnt int, err error) {
	sqlFmt := "select %v from md_books where book_name like ? or description like ? order by star desc"
	sql := fmt.Sprintf(sqlFmt, "book_id")
	sqlCount := fmt.Sprintf(sqlFmt, "count(book_id) cnt")

	keyword = "%" + keyword + "%"

	o := orm.NewOrm()
	var count struct{ Cnt int }
	err = o.Raw(sqlCount, keyword, keyword).QueryRow(&count)

	if count.Cnt > 0 {
		cnt = count.Cnt
		_, err = o.Raw(sql+" limit ? offset ?", keyword, keyword, size, (page-1)*size).QueryRows(&books)
	}

	return
}

/**
根据ID获取书本信息
*/
func (m *Book) GetBooksByIds(ids []int, fields ...string) (books []Book, err error) {
	if len(ids) == 0 {
		return
	}

	var bs []Book
	var idArr []interface{}

	for _, i := range ids {
		idArr = append(idArr, i)
	}

	rows, err := orm.NewOrm().QueryTable(TNBook()).Filter("book_id__in", idArr).All(&bs, fields...)
	if rows > 0 {
		bookMap := make(map[interface{}]Book)
		for _, book := range bs {
			bookMap[book.BookId] = book
		}

		for _, i := range ids {
			if book, ok := bookMap[i]; ok {
				books = append(books, book)
			}
		}
	}
	return
}
